package cn.edu.neu.vmmigeval.evaluation.loadevaluation;


import cn.edu.neu.vmmigeval.cloud.entity.Vm;

import java.util.List;

public class VmLoadEvaluation {
	
	private int vmNum;
	List<Vm> vms;
	
	public VmLoadEvaluation(){
		
	}
	
	public VmLoadEvaluation(List<Vm> vms) {
		if(vms==null){
			vmNum = 0;
		}else{
			this.vms= vms;
			vmNum = vms.size();
		}
	}
	public double getOneValue(double current,double total,int param){
		double result = (double)(current/total) *param;
		return result;
	}
	//�õ�����X
	public double[][] getXMatrix(){
		int vmSize = vms.size();
		double matrix[][] = new double[vmSize][7];
		for (int i = 0; i < vmSize; i++) {
			for (int j = 0; j < 7; j++) {
				if(j==0){
					matrix[i][j] = getOneValue(vms.get(i).getCurrentCpu(),vms.get(i).getTotalCpu(),100);
				}else if(j==1){
					matrix[i][j] = getOneValue(vms.get(i).getCurrentRam(),vms.get(i).getTotalRam(),100);
				}else if(j==2){
					matrix[i][j] = getOneValue(vms.get(i).getCurrentBw(),vms.get(i).getTotalBw(),100);
				}else if(j==3){
					matrix[i][j] = getOneValue(vms.get(i).getCurrentDisk(),vms.get(i).getTotalDisk(),100);
				}else if(j==4){
					matrix[i][j] = vms.get(i).getCurrentCpu();
				}else if(j==5){
					matrix[i][j] = vms.get(i).getCurrentRam();
				}else if(j==6){
					matrix[i][j] = vms.get(i).getCurrentBw();
				}
			}
		}
		matrix = new double[][]{
				{22,14,33,16,2000,2047,1024},
				{36,34,25,47,2400,2047,1024},
				{52,57,26,55,2700,4096,1024},
				{76,65,57,77,3200,4096,1024}
				};
		return matrix;
	}
	//�õ�����һ��֮��ľ���X'
	public double[][] getXSMatrix(){
		double[][] matrix = getXMatrix();
		double[][] xsMatrix = new double[vmNum][7];
		//ÿһ�е��ܺ�
		double[] eachRowSum = new double[7];
		for (int i = 0; i < vmNum; i++) {
			for (int j = 0; j < 7; j++) {
				eachRowSum[j]+= matrix[i][j];
			}
		}
		//��һ���ľ���
		for (int i = 0; i < vmNum; i++) {
			for (int j = 0; j < 7; j++) {
				xsMatrix[i][j] =  matrix[i][j]/eachRowSum[j];
			}
		}
		return xsMatrix;
	}
	//����Ȩ�ؾ���
	public double[][] getHostWeightedMatrix(){
		double[][] weightedMatrix = new double[7][7];
		for (int i = 0; i < 7; i++) {
			for (int j = 0; j < 7; j++) {
				if(i==j&&(i==0||i==1||i==4)){
					weightedMatrix[i][j] = 0.2;
				}else if(i==j){
					weightedMatrix[i][j] = 0.1;
				}else{
					weightedMatrix[i][j] = 0;
				}
			}
		}
		return weightedMatrix;
	}
	//�õ���Ȩ֮��ľ���
	public double[][] getXSWeightedMatrix(){
		//double[][] weightedMatrix = getHostWeightedMatrix();
		double[][] xsMatrix = getXSMatrix();
		double[] weightedMatrix = new double[]{0.2,0.2,0.1,0.1,0.2,0.1,0.1};
		double[][] xsWeightedMatrix = new double[vmNum][7];
		//�������
		for (int i = 0; i < vmNum; i++) {
			for (int j = 0; j < 7; j++) {
				xsWeightedMatrix[i][j]= xsMatrix[i][j]*weightedMatrix[j];
			}
		}
		return xsWeightedMatrix;
	}
	public double[] getBest(){
		double[][] xsWeightedMatrix = getXSWeightedMatrix();
		double[] z = new double[]{0,0,0,0,1,1,1};
		for (int i = 0; i < 7; i++) {
			//System.out.println("length is :"+xsWeightedMatrix.length);
			for (int j = 0; j < xsWeightedMatrix.length; j++) {
				if(i<4||i>6){
					if(xsWeightedMatrix[j][i]>z[i]){
						z[i] = xsWeightedMatrix[j][i];
					}
				}else{
					if(xsWeightedMatrix[j][i]<z[i]){
						z[i] = xsWeightedMatrix[j][i];
					}
				}
			}
			
		}
		return z;
	}
	public double[] getWorst(){
		double[][] xsWeightedMatrix = getXSWeightedMatrix();
		double[] z = new double[]{1,1,1,1,0,0,0};
		for (int i = 0; i < 7; i++) {
			for (int j = 0; j < xsWeightedMatrix.length; j++) {
				if(j<4||j>6){
					if(xsWeightedMatrix[j][i]<z[i]){
						z[i] = xsWeightedMatrix[j][i];
					}
				}else{
					if(xsWeightedMatrix[j][i]>z[i]){
						z[i] = xsWeightedMatrix[j][i];
					}
				}
			}
			
		}
		return z;
	}
	//�õ���þ����
	public double[] getBestS(){
		double[][] xsWeightedMatrix = getXSWeightedMatrix();
		double[] best = getBest();
		double[] bestS = new double[vmNum];
		double sumBest =0 ;
		for (int i = 0; i < vmNum; i++) {
			sumBest =0;
			for (int j = 0; j < 7; j++) {
				double pa =  xsWeightedMatrix[i][j]-best[j];
				sumBest+=pa*pa;
			}
			bestS[i] = Math.sqrt(sumBest);
		}
		return bestS;
		
	}
	//�õ�������
	public double[] getWorstS(){
		double[][] xsWeightedMatrix = getXSWeightedMatrix();
		double[] worst = getWorst();
		double[] worstS = new double[vmNum];
		double sumWorst =0;
		for (int i = 0; i < vmNum; i++) {
			sumWorst =0;
			for (int j = 0; j < 7; j++) {
				double pb =  xsWeightedMatrix[i][j]-worst[j];
				sumWorst+=pb*pb;
			}
			worstS[i] = Math.sqrt(sumWorst);
		}
		return worstS;
	}
	public double[] getFinal(){
		double[] bestS = getBestS();
		double[] worstS = getWorstS();
		double[] finalS = new double[vmNum];
		for (int i = 0; i < vmNum; i++) {
			finalS[i] = worstS[i]/(bestS[i]+worstS[i]);
			vms.get(i).setScore(finalS[i]);
		}
		return finalS;
	}
	/*public static void main(String[] args) {
		List<Vm> vms = new ArrayList<Vm>();
		vms.add(new Vm());
		vms.add(new Vm());
		vms.add(new Vm());
		vms.add(new Vm());
		VmLoadEvaluation le = new VmLoadEvaluation(vms);
		le.getFinal();
		for (Vm vm : vms) {
			System.out.println(vm.getScore());
		}
	
	}*/
	
}
